package com.alibaba.algo.domain.user;

import com.alibaba.algo.cooperation.feign.vo.req.SelectOrgUserEmployeeVO;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.EmployeeOrgAndPositionResponseVO;
import com.alibaba.algo.core.base.BaseDomain;
import com.alibaba.algo.core.base.BaseEntity;
import com.alibaba.algo.core.exception.BaseException;
import com.alibaba.algo.dao.user.SysEmployeeMapper;
import com.alibaba.algo.entity.user.SysEmployee;
import com.alibaba.algo.entity.user.SysOrg;
import com.alibaba.algo.entity.user.SysPosition;
import com.alibaba.algo.exception.BaseErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 类SysEmployee.java的实现描述：员工Domain
 *
 * @author nieganggang 2021-03-12 16:08:17
 */
@Component
@Slf4j
public class SysEmployeeDomain extends BaseDomain<SysEmployee> {

    @Resource
    private SysEmployeeMapper sysEmployeeMapper;
    @Autowired
    private SysOrgDomain orgDomain;
    @Autowired
    private SysPositionDomain positionDomain;

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    @Autowired
    private SysEmployeeOrgDomain employeeOrgDomain;
    @Autowired
    private SysEmployeePositionDomain employeePositionDomain;

    /**
     * 批量保存
     *
     * @param list
     * @return
     */
    public Long saveBatch(List<SysEmployee> list) throws PersistenceException {
        SqlSession sqlSession = null;
        try {
            sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
            SysEmployeeMapper mapper = sqlSession.getMapper(SysEmployeeMapper.class);
            for (SysEmployee employee : list) {
                Integer insert = mapper.insert(employee);
            }
            sqlSession.commit();
        } catch (PersistenceException e) {
            throw e;
        } finally {
            sqlSession.close();
        }
        return Long.valueOf(list.size());
    }


    /**
     * 查询员工关联的组织和岗位列表
     *
     * @param employeeId 员工标识
     * @return 员工关联的组织和岗位列表
     */
    public List<EmployeeOrgAndPositionResponseVO> selectOrgAndPositionList(Long employeeId) {
        if (ObjectUtils.isEmpty(employeeId)) {
            throw new BaseException(BaseErrorCode.EMPLOYEE_ID_IS_NULL.getCode(), BaseErrorCode.EMPLOYEE_ID_IS_NULL.getMessage());
        }
        return sysEmployeeMapper.selectOrgAndPositionList(employeeId);
    }

    /**
     * 通过员工列表查询员工信息
     *
     * @param employeeIdList 员工列表
     * @return 员工集合
     */
    public Map<Long, SysEmployee> qryEmployeeMapByIdList(List<Long> employeeIdList) {
        if (CollectionUtils.isEmpty(employeeIdList)) {
            return Collections.emptyMap();
        }

        SysEmployee sysEmployee = new SysEmployee();
        sysEmployee.setEmployeeIdList(employeeIdList);
        List<SysEmployee> sysEmployeeList = sysEmployeeMapper.listByPara(sysEmployee, null);
        return sysEmployeeList.stream().collect(Collectors.toMap(BaseEntity::getId, k -> k, (v1, v2) -> v2));
    }

    /**
     * 通过员工列表查询员工信息
     *
     * @param employeeIdList 员工列表
     * @return 员工集合
     */
    public List<SysEmployee> qryEmployeeListByIdList(List<Long> employeeIdList) {
        if (CollectionUtils.isEmpty(employeeIdList)) {
            return new ArrayList<>();
        }

        String sortStr="isnull(employee_order_no),employee_order_no+0,isnull(employee_code),employee_code";
        SysEmployee sysEmployee = new SysEmployee();
        sysEmployee.setEmployeeIdList(employeeIdList);
        List<SysEmployee> sysEmployeeList = sysEmployeeMapper.listByPara(sysEmployee, sortStr);
        return sysEmployeeList;
    }

    public SysEmployee selectByEmployeeCode(String employeeCode) {
        if (employeeCode == null || employeeCode.isEmpty()) {
            throw new RuntimeException("employeeCode不能为空");
        }
        SysEmployee sysEmployee = new SysEmployee();
        sysEmployee.setEmployeeCode(employeeCode);
        List<SysEmployee> list = sysEmployeeMapper.listByPara(sysEmployee, null);
        if (list != null && !list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    public SysEmployee selectByEmployeeCodeWithIsDeleted(String employeeCode) {
        if (employeeCode == null || employeeCode.isEmpty()) {
            throw new RuntimeException("employeeCode不能为空");
        }
        SysEmployee sysEmployee = new SysEmployee();
        sysEmployee.setEmployeeCode(employeeCode);
        List<SysEmployee> list = sysEmployeeMapper.listByParaWithIsDeleted(sysEmployee, null);
        if (list != null && !list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    /**
     * 根据employcode 批量判断存在的员工
     *
     * @param list
     * @return
     */
    public Integer batchCount(List<SysEmployee> list) {
        if (ObjectUtils.isEmpty(list)) {
            return 0;
        }
        return sysEmployeeMapper.countByEmployeeList(list);
    }


    /**
     * 根据employeeCode列表查询数据库中已经存在的员工
     *
     * @param list
     * @return
     */

    public List<String> listByCodes(List<String> list) {
        ArrayList<String> resp = Lists.newArrayList();
        if (ObjectUtils.isEmpty(list)) {
            return resp;
        }
        return sysEmployeeMapper.listByCodes(list);
    }

    /**
     * 查询组织名称是否存在，如果存在，获取到orgId
     *
     * @param data
     * @return
     */
    public boolean isOrgNameExist(SysEmployee data) {
        SysOrg org = orgDomain.qryOrgByOrgName(data.getOrgName());
        if (org == null) {
            return false;
        }
        data.setOrgId(org.getId());
        return true;
    }

    /**
     * 检验岗位名称是否存在。同时维护岗位ID
     *
     * @param data
     * @return
     */
    public boolean qryPosition(SysEmployee data) {
        SysPosition sysPosition = new SysPosition();
        sysPosition.setOrgId(data.getOrgId());
        sysPosition.setName(data.getPositionName());
        SysPosition position = positionDomain.getOne(sysPosition);
        if (position == null) {
            return false;
        }
        data.setPositionId(position.getId());
        return true;

    }

    /**
     * 导入员工。存数据库。保存或者更新sys_employee
     * 维护sys_employee_org  sys_employee_position
     *
     * @param list
     */
    public void saveOrUpdateBatch(List<SysEmployee> list) {
        if (ObjectUtils.isEmpty(list)) {
            return;
        }
        for (SysEmployee employee : list) {
            SysEmployee empFromTable = this.selectByEmployeeCode(employee.getEmployeeCode());
            LocalDateTime now = LocalDateTime.now();
            if (ObjectUtils.isEmpty(empFromTable)) {
                employee.setGmtModified(now);
                employee.setGmtCreated(now);
                insert(employee);
            } else {
                employee.setId(empFromTable.getId());
                employee.setGmtModified(now);
            }
            Long employeeId = employee.getId();
            Long orgId = employee.getOrgId();
            employeeOrgDomain.judgeAndInsert(employeeId, orgId);
            Long positionId = employee.getPositionId();
            if (ObjectUtils.isEmpty(positionId)) {
                return;
            }
            employeePositionDomain.judgeAndInsert(employeeId, positionId);
        }
    }

    public List<SysEmployee> selectListByCondition(SelectOrgUserEmployeeVO vo){
        return sysEmployeeMapper.selectListByCondition(vo);
    }

    /**
     * 根据员工code查询员工信息
     * @param employeeCode
     * @return
     */
    public SysEmployee selectEmployeeByEmployeeCode(String employeeCode) {
        return sysEmployeeMapper.selectEmployeeByEmployeeCode(employeeCode);
    }

    public List<SysEmployee> selectListByUserAccount(SelectOrgUserEmployeeVO vo){
        return sysEmployeeMapper.selectListByUserAccount(vo);
    }

    public Integer deleteById(Long employeeId){
        return sysEmployeeMapper.deleteById(employeeId);
    }

    public Map<String, SysEmployee> qryEmployeeNameMapByCodes(List<String> employeeCodeList) {
        if (CollectionUtils.isEmpty(employeeCodeList)) {
            return Collections.emptyMap();
        }
        SysEmployee sysEmployee = new SysEmployee();
        sysEmployee.setEmployeeCodeList(employeeCodeList);
        List<SysEmployee> sysEmployeeList = sysEmployeeMapper.listByParaDefaultAll(sysEmployee, null);
        return sysEmployeeList.stream().collect(Collectors.toMap(SysEmployee::getEmployeeCode, k -> k, (v1, v2) -> v2));
    }

    public int updateByIdWithIsDeleted(SysEmployee entity) {
        return sysEmployeeMapper.updateByIdWithIsDeleted(entity);
    }

    public List<SysEmployee> listByParaWithIsDeleted(SysEmployee entity){
        return sysEmployeeMapper.listByParaWithIsDeleted(entity, null);
    }
}
